package com.psbc.pfpj;

import cfca.sadk.algorithm.sm2.SM2PublicKey;
import cfca.sadk.lib.crypto.JCrypto;
import cfca.sadk.lib.crypto.Session;
import cfca.sadk.org.bouncycastle.util.encoders.Hex;
import cfca.sadk.util.KeyUtil;
import cfca.sadk.util.Signature;
import com.alibaba.fastjson.JSONObject;
import com.psbc.pfpj.commons.SSLOkHttpClient;
import com.psbc.pfpj.dto.RequestMerchant;
import okhttp3.*;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Base64;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.psbc.pfpj.config.PropertiesConfig.THIRDPARTY;

/**
 * @author whj
 */
public class MerchantAccessDemo {
    private static final String SM2_FILE = THIRDPARTY.getString("sm2-file");
    private static final String SM2_PASSWORD = THIRDPARTY.getString("sm2-password");
    private static final String DEVICE_NAME = THIRDPARTY.getString("device-name");
    private static final String SIGNATURE_ALGORITHM = THIRDPARTY.getString("signature-algorithm");
    private static final String PUBLIC_KEY = THIRDPARTY.getString("public-key");
    private static final Signature UTIL = new Signature();


    /***
     * 商户接入数币测试服务
     * @param jsonObject 接口参数
     * @param requestPath 调用接口地址
     * @param sourceData 加签参数
     * @param responseSource 解签参数
     */
    public static void testService(JSONObject jsonObject, String requestPath, byte[] sourceData, RequestMerchant merchant) {
        try {
            JCrypto.getInstance().initialize(DEVICE_NAME, null);
            Session session = JCrypto.getInstance().openSession(DEVICE_NAME);
            PrivateKey priKey = KeyUtil.getPrivateKeyFromSM2(SM2_FILE, SM2_PASSWORD);
            // 校验，必须指定签名算法
            byte[] base64P1SignedData = UTIL.p1SignMessage(SIGNATURE_ALGORITHM, sourceData, priKey, session);
            //签名转换成字符串
            String signData = new String(base64P1SignedData);
            jsonObject.put("signature", signData);
            OkHttpClient client = new OkHttpClient.Builder()
                    .readTimeout(60, TimeUnit.SECONDS)
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .sslSocketFactory(SSLOkHttpClient.getSSLSocketFactory(), SSLOkHttpClient.getX509TrustManager())
                    .hostnameVerifier(SSLOkHttpClient.getHostnameVerifier())
                    .build();
            MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
            RequestBody body = RequestBody.Companion.create(jsonObject.toJSONString(), mediaType);
            Request request = new Request.Builder()
                    .url(requestPath).post(body).build();
            Call call = client.newCall(request);
            Response response = call.execute();
            String resultStr = Objects.requireNonNull(response.body()).string();
            System.out.println(signData);
            System.out.println("post返回状态：" + response.code());
            System.out.println("post返回结果：" + resultStr);
            JSONObject resultJson = JSONObject.parseObject(resultStr);
            //获取返回的密文
            String signature = resultJson.getString("signature");
            String reqTraceID = resultJson.getString("reqTraceID");
            StringBuilder stringBuffer = new StringBuilder();
            stringBuffer.append(merchant.getTxnCode()).append(" ").append(reqTraceID).append(" ").append(merchant.getReqDate());
            if (null != merchant.getTxnAmt()) {
                stringBuffer.append(" ").append(merchant.getTxnAmt());
            }
            if (!StringUtils.isEmpty(merchant.getMchtNo())) {
                stringBuffer.append(" ").append(merchant.getMchtNo());
            }
            if (!StringUtils.isEmpty(merchant.getTermID())) {
                stringBuffer.append(" ").append(merchant.getTermID());
            }
            if (!StringUtils.isEmpty(merchant.getCreditorWalletId())) {
                stringBuffer.append(" ").append(merchant.getCreditorWalletId());
            }
            if (!StringUtils.isEmpty(merchant.getDebtorWalletId())) {
                stringBuffer.append(" ").append(merchant.getDebtorWalletId());
            }
            //获取sm2公钥
            SM2PublicKey sm2PublicKey = KeyUtil.getSM2PublicKey(Base64.getEncoder().encodeToString(Hex.decode(PUBLIC_KEY.getBytes())).getBytes("UTF-8"));
            //对响应内容验签
            boolean verifyResult = UTIL.p1VerifyMessage(SIGNATURE_ALGORITHM, stringBuffer.toString().getBytes(StandardCharsets.UTF_8), signature.getBytes(), sm2PublicKey, session);
            System.out.println("verifyResult---------" + verifyResult);
            response.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

}
